package mvc

import (
	"go-framework/log"
	"html/template"
	"net/http"
	"strings"
)

type HandlerFunc func(context *Context)

type MVC struct {
	name    string
	version string
	address string
	//state chan
	router *router
	*RouterGroup

	groups []*RouterGroup // store all groups

	htmlTemplates *template.Template // for html render
	funcMap       template.FuncMap   // for html render
}

func New(address string) *MVC {
	if address == "" {
		address = "0.0.0.0:9000"
	}
	return &MVC{
		name:    "mvc",
		version: "v0.0.1",
		address: address,
		router:  newRouter(),
	}
}

func (mvc *MVC) addRoute(method string, pattern string, handler HandlerFunc) {
	mvc.router.addRoute(method, pattern, handler)
}

// GET defines the method to add GET request
func (mvc *MVC) GET(pattern string, handler HandlerFunc) {
	mvc.addRoute("GET", pattern, handler)
}

// POST defines the method to add POST request
func (mvc *MVC) POST(pattern string, handler HandlerFunc) {
	mvc.addRoute("POST", pattern, handler)
}

func (mvc *MVC) Name() string {
	return mvc.name
}

func (mvc *MVC) Version() string {
	return mvc.version
}

func (mvc *MVC) Start() {
	log.Logger.Info("mvc", "server is starting in "+mvc.address)
	http.ListenAndServe(mvc.address, mvc)
}

func (mvc *MVC) Stop() {

}

func (mvc *MVC) SetFuncMap(funcMap template.FuncMap) {
	mvc.funcMap = funcMap
}

func (engine *MVC) LoadHTMLGlob(pattern string) {
	engine.htmlTemplates = template.Must(template.New("").Funcs(engine.funcMap).ParseGlob(pattern))
}

func (mvc *MVC) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	/**设置插件,并和分组挂钩**/
	var middlewares []HandlerFunc
	for _, group := range mvc.groups {
		if strings.HasPrefix(req.URL.Path, group.prefix) {
			middlewares = append(middlewares, group.middlewares...)
		}
	}
	c := newContext(w, req)
	c.handlers = middlewares
	c.MVC = mvc
	mvc.router.handle(c)
}
